﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.SessionState;
using System.Drawing;
using System.Drawing.Imaging;
using System.Data;

namespace QXBook.Handlers.OtherHandlers
{
    public enum ValidateCodeType
    {
        ValidateCode,
        Math
    };

    public sealed class ValidateCodeHandler : IHttpHandler, IRequiresSessionState
    {
        /// <summary> 
        /// 构造函数 
        /// </summary> 
        public ValidateCodeHandler()
        { }

        #region 私有字段
        private ValidateCodeType m_CodeType = ValidateCodeType.Math;

        /// <summary> 
        /// 验证码的长度 
        /// </summary> 
        private int m_CodeLength = 5;

        /// <summary> 
        /// 保存到会话状态中的值 
        /// </summary> 
        private string m_SessionName = "validateCode";

        /// <summary> 
        /// 图像的宽 
        /// </summary> 
        private int m_ImageWidth = 135;

        /// <summary> 
        /// 图像的长 
        /// </summary> 
        private int m_ImageHeight = 42;

        /// <summary> 
        /// 图像背景色 
        /// </summary> 
        private Color m_BackgroundColor = Color.FromArgb(212, 236, 189);

        /// <summary> 
        /// 图像上验证码的颜色 
        /// </summary> 
        private Color m_CodeColor = Color.FromArgb(132, 199, 1);

        /// <summary> 
        /// 干扰图形的颜色 
        /// </summary> 
        private Color m_ObstructionColor = Color.Gray;

        /// <summary> 
        /// 用来生成随机验证码的字符串 
        /// </summary> 
        private const string m_CodeString = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";

        private const string m_OperatorString = "+-";

        private const string m_ResultString = "=?";

        #endregion

        #region IHttpHandler 成员

        /// <summary> 
        /// 是否可以重用 
        /// </summary> 
        public bool IsReusable
        {
            get { return true; }
        }

        /// <summary> 
        /// 处理请求 
        /// </summary> 
        /// <param name="context"></param> 
        public void ProcessRequest(HttpContext context)
        {
            ///设置输出的格式 
            context.Response.ContentType = "image/gif";
            Random random = new Random();
            ///用来保存随机取得的字符串 
            StringBuilder s = new StringBuilder();
            ///创建绘图的图像 
            using (Bitmap bitmap = new Bitmap(this.m_ImageWidth, this.m_ImageHeight))
            {
                ///创建绘图图面，用此对象将各种符号等绘制到制定的图像上 
                using (Graphics graphics = Graphics.FromImage(bitmap))
                {
                    ///生成背景颜色 
                    graphics.FillRectangle(new SolidBrush(this.m_BackgroundColor), 0, 0, this.m_ImageWidth, this.m_ImageHeight);

                    #region 生成验证码
                    ///验证码的字体 
                    using (Font font = new Font(FontFamily.GenericSerif, 32, FontStyle.Bold | FontStyle.Italic, GraphicsUnit.Pixel))
                    {
                        if (m_CodeType == ValidateCodeType.ValidateCode)
                        {
                            for (int i = 0; i < this.m_CodeLength; i++)
                            {
                                s.Append(ValidateCodeHandler.m_CodeString.Substring(random.Next(0, m_CodeString.Length - 1), 1));
                                ///将字符绘制到图像上 
                                graphics.DrawString(s[s.Length - 1].ToString(), font, new SolidBrush(this.m_CodeColor), i * 25, random.Next(0, 8));
                            }
                        }
                        else
                        {
                            double a = random.Next(0,99);
                            double b = random.Next(0,99);
                            string expression = a.ToString() + ValidateCodeHandler.m_OperatorString.Substring(random.Next(0, m_OperatorString.Length - 1), 1) + b.ToString();
                            DataTable eval = new DataTable();
                            object result = eval.Compute(expression, "");

                            graphics.DrawString(expression + m_ResultString, font, new SolidBrush(this.m_CodeColor), 2, random.Next(0, 8));

                            ///保存图像到输出流 
                            bitmap.Save(context.Response.OutputStream, ImageFormat.Gif);
                            context.Session[this.m_SessionName] = result;
                            context.Response.End();
                            return;
                        }
                    }
                    #endregion

                    #region 绘制干扰图形和噪点

                    //干扰图形绘制画笔 
                    using (Pen pen = new Pen(new SolidBrush(this.m_ObstructionColor), 1))
                    {
                        for (int i = 0; i < 10; i++)
                        {
                            graphics.DrawLine(pen, new Point(random.Next(0, this.m_ImageWidth - 1), random.Next(0, this.m_ImageHeight - 1)), new Point(random.Next(0, this.m_ImageWidth - 1), random.Next(0, this.m_ImageHeight - 1)));
                        }
                    }

                    for (int i = 0; i < 100; i++)
                    {
                        bitmap.SetPixel(random.Next(this.m_ImageWidth), random.Next(this.m_ImageHeight), Color.FromArgb(random.Next()));
                    }
                    #endregion

                    ///保存图像到输出流 
                    bitmap.Save(context.Response.OutputStream, ImageFormat.Gif);
                }
            }
            ///将验证码的值保存到用户会话状态中,并且不区分大小写 
            context.Session[this.m_SessionName] = s.ToString().ToLower();
            context.Response.End();
        }

        #endregion
    }
}
